<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Lucene Powered Swing Data Models</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head>
<body>
<h1><strong> Lucene Powered Swing Data Models </strong></h1>
<p><strong>by Jonathan Simon </strong></p>
<p>&nbsp;</p>
<p><strong>What it is.</strong></p>
<p>This package contains classes that help you easily integrate Lucene based searching 
  into your Swing components. Currently there are classes to index and search 
  JTables and JLists. This is done using model decorators rather than custom models 
  to make it easier to search current models as well as new ones. </p>
<p><em>These models do not actually contain any data</em>. Rather, the ListModel 
  decorator (ListSearcher) and the TableModel decorator (TableSearcher) take a 
  model in the constructor and delegate all calls to it (after a little alteration, 
  but we'll get to that). That said, these are not full fledged models themselves. 
  You still have to have another model to decorate with the searching models. 
  If you are adding searching to a pre-existing model, you can use your pre-existing 
  model directly. Otherwise, you can implement a model from scratch or use a pre-existing 
  one to get started. </p>
<p><strong>What it isn't. </strong></p>
<p>A complete component: These are just models. They are not complete components 
  with search fields and buttons laid out like a searchable interface. You still 
  have to build that since the UI changes drastically between applciations.</p>
<p>A complete model: There are just model decorators. You can't just set the model 
  of a JList or JTable to one of these models, and you can't add data directly 
  to these models. </p>
<p>A front end for a lucene index: In other words, you can't use these classes 
  to point a JTable directly to a Lucene index. Although that's interesting in 
  its own right, this is not that. </p>
<p><strong>Usage: </strong></p>
<p>Coding to both models nearly identical. They both take the model to decorate 
  at construction time. Here is the code from the demo to decorate a JTable model 
  with the TableSearcher and set it as the table model. </p>
<pre><code>//make a new JTable
JTable table = new JTable();
//make my base model, the model with the data
BaseTableModel tableModel = new BaseTableModel(DataStore.getRestaurants());
//decorate the tableModel with the TableSearcher 
TableSearcher searchTableModel = new TableSearcher(tableModel);
//set the TableModel in the table to the TableSearcher
table.setModel(searchTableModel);
</code></pre>
<p>Initially, you won't notice a difference. This is because there is no active 
  search which displays all data from the underlying model. You search by calling 
  the <code>search</code>() method passing a search string. This filters the data 
  set down without changing the underlying data model -- one of the main reasons 
  for decorating in the first place. Any valid Lucene search string should work 
  (see notes for more info on this). You'll probaby have some code somewhere like 
  this in your app to connect a text field and search button to the model. </p>
<pre><code>//create components
final JTextField searchField = new JTextField();
JButton searchButton = new JButton("Go");

//make an action listener
ActionListener searchListener = new ActionListener() {
	public void actionPerformed(ActionEvent e) {
	   searchTableModel.search(searchField.getText().trim().toLowerCase());
	}
};

//register listeners
searchButton.addActionListener(searchListener);
searchField.addActionListener(searchListener);</code></pre>
<p>You also might want to have a clear search button, working the same way. But 
  to keep things simple, if you search will a <code>null </code>String or an empty 
  String, the search clears and you will once again see all of your data. </p>
<p><strong>Demo notes:</strong> </p>
<p>The list demo does real time searching. In other words, as you type, searches 
  run and the result set updates. The table demo has a search button, and only 
  searches when the button is clicked. They both work, I just implemented them 
  this way to show the different UI metaphors and that they both work.</p>
<p><strong>Implementation notes: </strong></p>
<p>This code started as a proof of concept so it's not a <em>fully</em> featured 
  model. Don't get me wrong, it <em>fully</em> works, but it could use some improvement 
  that it will hopefully get over time. I just wanted to get it out there and 
  get people using it. I'm also trying to keep everything as simple as possible. 
  Here are some of the issues. </p>
<ul>
  <li>You can't change the model after the Searcher is constructed. </li>
  <li>The search model decorators <em>do</em> update when the decorated model 
    is updated, but not in a very efficient way. The whole search model is reindexed 
    when anything changes. This is a definite scaling issue. </li>
  <li>The indexing and searching logic needs to be generally more configurable 
    to allow custom tailoring of searched and indexing. </li>
  <li>The TableSearcher uses column names to index column values. This could be 
    an issue with multiple word column names. </li>
  <li>The ListSearcher uses MultiFieldQueryParser even though its not really indexing 
    multiple fields. </li>
</ul>
<p>&nbsp;</p>
<p>&nbsp;</p>
</body>
</html>
